package controllers

import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"os"
	"strconv"
	"strings"

	md "gitee.com/countpoison/youbei/models"
	"github.com/astaxie/beego"
)

// uploadfile ...
type uploadfile struct {
	ID        string `json:"id"`
	FileName  string `json:"filename"`
	SaveDir   string `json:"savedir"`
	Size      int64  `json:"size"`
	PacketNum int64  `json:"packetnum"`
}

//EnableServer 启动本地存储
func (c *MainController) EnableServer() {
	ob := new(md.Yserver)
	c.APIReturn(500, "解析失败", json.Unmarshal(c.Ctx.Input.RequestBody, ob))
	c.APIReturn(500, "服务启动失败", ob.EnableYserver())
	c.APIReturn(200, "服务启动成功", nil)
}

//Yserverlist 本地存储查询
func (c *MainController) Yserverlist() {
	ys := md.Yserver{}
	bol, err := md.Localdb().Get(&ys)
	c.APIReturn(500, "查询Yserver失败", err)
	if !bol {
		c.APIReturn(500, "Yserver不存在", errors.New("Yserver不存在"))
	}
	ys.Port, err = beego.AppConfig.Int("httpport")
	c.APIReturn(500, "端口获取失败", err)
	c.APIReturn(200, "获取成功", ys)
}

//DisableServer 关闭本地存储
func (c *MainController) DisableServer() {
	ob := new(md.Yserver)
	c.APIReturn(500, "解析失败", json.Unmarshal(c.Ctx.Input.RequestBody, ob))
	c.APIReturn(500, "服务关闭失败", ob.EnableYserver())
	c.APIReturn(200, "服务关闭成功", nil)
}

//UploadFile 新增上传文件任务
func (c *LoginController) UploadFile() {
	ys := md.Yserver{}
	bol, err := md.Localdb().Get(&ys)
	c.APIReturn(500, "查询Yserver失败", err)
	if !bol {
		c.APIReturn(500, "Yserver不存在", errors.New("Yserver不存在"))
	}
	if !ys.Enable {
		c.APIReturn(500, "Yserver未启动", errors.New("Yserver未启动"))
	}
	if c.GetString("username") != ys.Username || c.GetString("password") != ys.Password {
		c.APIReturn(500, "账号密码错误", errors.New("账号密码错误"))
	}
	var ob uploadfile

	ob.ID = c.Ctx.Input.Param(":id")
	ob.FileName = c.GetString("filename")
	ob.Size, err = c.GetInt64("size")
	c.APIReturn(500, "fsize not found", err)
	ob.SaveDir = c.GetString("savedir")
	ob.PacketNum, err = c.GetInt64("packetnum")
	c.APIReturn(500, "packet not found", err)
	c.APIReturn(500, "录入失败", md.AddFile(ob.ID, ob.FileName, ob.SaveDir, ob.Size, ob.PacketNum))
	c.APIReturn(200, "录入成功", nil)

}

//Uploadpacket 上传分片包
func (c *LoginController) Uploadpacket() {
	id := c.Ctx.Input.Param(":id")
	sort := c.Ctx.Input.Param(":sort")
	sortid, _ := strconv.Atoi(sort)
	packetname := id + "_" + sort
	os.MkdirAll("temp_server_upload_file", os.ModeDir)
	f, err := os.Create("temp_server_upload_file/" + packetname)
	defer f.Close()
	c.APIReturn(500, "文件创建失败", err)
	_, err = f.Write(c.Ctx.Input.RequestBody)
	c.APIReturn(500, "文件写入失败", err)
	c.APIReturn(500, "切片记录失败", md.AddPacket(id, sortid, "temp_server_upload_file/"+packetname))
	go mergePacket(id)
	c.APIReturn(200, packetname, nil)

}

//mergePacket 包合并
func mergePacket(id string) {
	yp, err := md.FindFile(id)
	if err != nil {
		fmt.Println(1, err)
		return
	}
	ps, err := md.AllPacket(id)
	if err != nil {
		fmt.Println(2, err)
		return
	}
	if int(yp.Packet) == len(ps) {
		fs := md.Yserver{}
		bol, err := md.Localdb().Get(&fs)
		if err != nil || !bol {
			return
		}

		fs.SavePath = strings.TrimRight(fs.SavePath, "/")
		if fs.SavePath == "" {
			fs.SavePath = "."
		}
		f, err := os.OpenFile(fs.SavePath+"/"+yp.FileName, os.O_CREATE|os.O_WRONLY|os.O_APPEND, os.ModePerm)
		defer f.Close()
		if err != nil {
			fmt.Println(4, err)
			return
		}
		for _, v := range ps {
			p, err := os.OpenFile(v.PacketPath, os.O_RDONLY, os.ModePerm)
			if err != nil {
				fmt.Println(5, err)
				return
			}
			b, err := ioutil.ReadAll(p)
			if err != nil {
				fmt.Println(6, err)
				return
			}
			f.Write(b)
			p.Close()
			os.Remove(v.PacketPath)
		}
		if err = md.FinshFile(id); err != nil {
			fmt.Println(7, err)
			return
		}
	}
	return
}

//Uploadlogs 存储日志查询
func (c *MainController) Uploadlogs() {
	id := c.Ctx.Input.Param(":id")
	page, _ := c.GetInt("page")
	count, _ := c.GetInt("count")
	if id == "" {
		yps, err := md.AllFile(page, count)
		c.APIReturn(500, "查询失败1", err)
		total, err := md.Filecount()
		c.APIReturn(500, "查询总数失败", err)
		rep := map[string]interface{}{"count": total, "data": yps}
		c.APIReturn(200, "查询成功", &rep)
	} else {
		yp, err := md.FindFile(id)
		c.APIReturn(500, "查询失败2", err)
		c.APIReturn(200, "查询成功", yp)
	}

}
